/*
 * sgc_list.c
 *
 *  Created on: 2011-7-5
 *      Author: rendong01
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "sgc_log.h"
#include "sgc_list.h"


/**
 * 创建
 */
sgc_list_t * sgc_list_create()
{
	sgc_list_t * list = (sgc_list_t *)malloc(sizeof(sgc_list_t));

	list->head = NULL;
	list->last = NULL;
	list->size = 0;

	return list;
}


/**
 * 添加元素到列表尾部
 */
void sgc_list_push(sgc_list_t *list, void *elements)
{
	sgc_list_item_t * item = (sgc_list_item_t *)malloc(sizeof(sgc_list_item_t));
	item->elts = elements;
	item->next = NULL;
	item->pre = NULL;

	if (list->head == NULL)
	{
		list->head = item;
		list->last = item;
		list->size = 1;
	}else{
		list->last->next = item;
		item->pre = list->last;

		list->last = item;
		list->size++;
	}
#ifdef DEBUG_LIST
	sgc_log_debug("sgc_list_push:%x, size:%d\n", list, list->size);
#endif
}


/**
 * 将尾部元素弹出,并返回元素本身
 */
void * sgc_list_pop(sgc_list_t *list)
{
	if (list->size == 0){
		return NULL;
	}else{
		sgc_list_item_t * item = list->last;
		list->last = item->pre;

		list->size--;

		void * data = item->elts;
		free(item);

#ifdef DEBUG_LIST
		sgc_log_debug("sgc_list_pop:%x, size:%d\n", list, list->size);
#endif
		return data;
	}
}

/**
 * 将头部元素弹出
 */
void * sgc_list_shift(sgc_list_t *list)
{
	if (list->size == 0){
		return NULL;
	}else{
		sgc_list_item_t * head = list->head;
		list->head = head->next;

		list->size--;

		void * data = head->elts;
		free(head);

#ifdef DEBUG_LIST
		sgc_log_debug("sgc_list_shift:%x, size:%d\n", list, list->size);
#endif
		return data;
	}
}

/**
 * 添加元素到列表头部
 */
void sgc_list_unshift(sgc_list_t *list, void *elements)
{
	sgc_list_item_t * item = (sgc_list_item_t *)malloc(sizeof(sgc_list_item_t));
	item->elts = elements;
	item->next = NULL;
	item->pre = NULL;

	if (list->head == NULL)
	{
		list->head = item;
		list->last = item;
		list->size = 1;
	}else{
		item->next = list->head;

		list->head = item;

		list->size++;
	}

#ifdef DEBUG_LIST
	sgc_log_debug("sgc_list_unshift:%x, size:%d\n", list, list->size);
#endif
}

/**
 * 删除元素
 */
void sgc_list_del(sgc_list_t *list, void *elements)
{
	sgc_list_item_t * item;

	item = list->head;
	if (item == NULL)
		return;

	// 头节点判断
	if (item->elts == elements){
		list->head = item->next;

		if (list->last == item)
			list->last = NULL;

		list->size--;

		free(item);
	}else{
		while(item != NULL){
			if (item->elts == elements){
				item->pre->next = item->next;

				if (item->next != NULL)
					item->next->pre = item->pre;

				if (list->last == item)
					list->last = item->pre;

				list->size--;

				free(item);
				break;
			}else{
				item = item->next;
			}
		}
	}

#ifdef DEBUG_LIST
	sgc_log_debug("sgc_list_del:%x, size:%d\n", list, list->size);
#endif
}


/**
 * 对每个元素进行遍历
 */
void sgc_list_foreach(sgc_list_t *list, void *data, void (*handler)(void *elements, int index, void * data))
{
	sgc_list_item_t *head;
	head = list->head;
	int index = 0;

	if (head == NULL)
		return;

	while(head->next != NULL)
	{
		handler(head->elts, index, data);

		head = head->next;
		index++;
	}

	// 尾部节点
	if (head != NULL){
		handler(head->elts, index, data);
	}
}

/**
void sgc_list_destory(sgc_list_t *list)
{
	sgc_list_item_t *last, *tmp;

	last = list->last;
	while (last != NULL){
		tmp = last;
		last = last->pre;
		free(tmp);
	}

	free(list);
}
**/
